package com.alibaba.citrus.cr.order.open.api.facade.service.notifyquantity;

import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.order.open.api.facade.model.FulfillmentOrderData;
import com.alibaba.citrus.cr.order.open.api.facade.model.TransferAndForecastOrder;
import com.alibaba.citrus.cr.order.open.api.facade.model.TransferAndForecastOrderQueryRequest;
import com.alibaba.citrus.cr.order.open.api.facade.model.TransferOrder;
import com.alibaba.citrus.cr.order.open.api.facade.model.TransferOrderQueryRequest;
import com.alibaba.citrus.cr.order.open.api.facade.transferforecastorder.TransferForecastOrderQueryService;
import com.alibaba.citrus.cr.order.open.api.facade.transferorder.TransferOrderQueryService;
import com.alibaba.citrus.cr.unified.inventory.contants.FeaturesKey;
import com.alibaba.citrus.cr.unified.inventory.utils.CompareUtil;
import com.alibaba.citrus.cr.unified.inventory.utils.InfoUtil;
import com.alibaba.cloud.retail.delivery.api.model.delivery.enums.FulfillmentDirectionTypeEnum;
import com.alibaba.cloud.retail.delivery.api.model.delivery.response.fulfillment.FulfillmentDetailGetRes;
import com.alibaba.cloud.retail.delivery.api.model.delivery.response.fulfillment.FulfillmentGetRes;
import com.alibaba.cloud.retail.delivery.api.model.fulfillment.request.SearchFulfullmentOrderReq;
import com.alibaba.cloud.retail.delivery.api.service.bcfulfillment.FulfillmentOrderAbilityService;
import com.alibaba.cz.base.tool.FeatureUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorderdetail.service.AllocateApplyOrderDetailService;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.dto.UpdateFeaturesRequest;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.model.AllocateOrderDetail;
import com.epoch.app.crunifiedinventory.domain.allocateorderdetail.service.AllocateOrderDetailService;
import com.epoch.app.crunifiedinventory.sdo.enums.AllocateOrderTypeEnum;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: yuhw
 * @date: 2024年02月29日 11:14
 **/
@Component
public class FulfillmentFreightYardNotifyQuantityHandler implements FulfillmentNotifyQuantityHandler {
    private static Log log = Log.getLogger(FulfillmentFreightYardNotifyQuantityHandler.class);

    @Resource
    private TransferOrderQueryService transferOrderQueryService;
    @Resource
    private AllocateOrderDetailService allocateOrderDetailService;
    @Resource
    private AllocateApplyOrderDetailService allocateApplyOrderDetailService;
    @DubboReference(protocol = "dubbo", check = false)
    private FulfillmentOrderAbilityService fulfillmentOrderAbilityService;
    @Resource
    private TransferForecastOrderQueryService transferForecastOrderQueryService;

    @Override
    public void handle(FulfillmentOrderData FulfillmentOrderData) {
        //解析出履约单对象
        List<FulfillmentGetRes> fulfillmentGetRes = getFulfillmentGetRes(FulfillmentOrderData);
        if (CollectionUtils.isEmpty(fulfillmentGetRes)){
            throw new FacadeException("OTS-03-005-00-15-230","查询履约单");
        }
        //拿到调拨单对象
        //根据行号匹配到调拨单行, 更新调拨单行的履约数量
        //更新对应的调拨预报单行的
        TransferOrder transferOrder = getTransferOrder(FulfillmentOrderData);
        transferOrder.getDetailList().forEach(transferSubOrder -> {
            //匹配上调拨单的行
            List<FulfillmentDetailGetRes> fulfillmentDetailGetRes = fulfillmentGetRes.stream().filter(res -> CollectionUtils.isNotEmpty(res.getDetailList()))
                    .flatMap(res -> res.getDetailList().stream())
                    .filter(detail -> !CompareUtil.anyOf(detail.getStatus(),excludeFulfillmentOrderStatusList.toArray(new String[0])))
                    .filter(detail -> Objects.equals(transferSubOrder.getLineNo(),detail.getRefOrderLineNo()))
                    .collect(Collectors.toList());
            if (CollectionUtils.isEmpty(fulfillmentDetailGetRes)){
                log.info("FulfillmentPlanNotifyQuantityHandler_not_match_line,lineNo:{}",transferSubOrder.getLineNo());
//                return;
            }
            BigDecimal fulfillmentQuantity = fulfillmentDetailGetRes.stream().map(FulfillmentDetailGetRes::getQuantity)
                    .filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
            AllocateOrderDetailService allocateOrderDetailService = getAllocateOrderDetailService();
            UpdateFeaturesRequest updateFeaturesRequest = new UpdateFeaturesRequest();
            updateFeaturesRequest.setMainOrderCode(transferOrder.getTransferOrderCode());
            updateFeaturesRequest.setLineNo(transferSubOrder.getLineNo());
            Map<String, String> bizFeatures = MapUtils.emptyIfNull(transferSubOrder.getBizFeatures());
            bizFeatures.put(FeaturesKey.CUMULATIVE_FULFILLMENT_NOTIFY_QUANTITY,fulfillmentQuantity.toString());
            updateFeaturesRequest.setBizFeatures(FeatureUtil.toString(bizFeatures));
            log.info("FulfillmentPlanNotifyQuantityHandler_updateFeatures:{}", JSON.toJSONString(updateFeaturesRequest));
            allocateOrderDetailService.updateFeatures(updateFeaturesRequest);
        });
        if (StringUtils.isBlank(transferOrder.getAllocateApplyOrderId())){
            log.info("FulfillmentFreightYardNotifyQuantityHandler_not_has_applyOrder");
            return;
        }
        TransferAndForecastOrderQueryRequest forecastOrderQueryRequest = new TransferAndForecastOrderQueryRequest();
        forecastOrderQueryRequest.setTransferForecastOrderId(Long.valueOf(transferOrder.getAllocateApplyOrderId()));
        Result<TransferAndForecastOrder> transferAndForecastOrderResult = transferForecastOrderQueryService.queryTransferAndForecastOrder(forecastOrderQueryRequest);
        if (transferAndForecastOrderResult == null || !transferAndForecastOrderResult.isSuccess()
            || transferAndForecastOrderResult.getResult().getAllocateApplyOrder() == null
            || CollectionUtils.isEmpty(transferAndForecastOrderResult.getResult().getAllocateApplyOrderDetails())
            || CollectionUtils.isEmpty(transferAndForecastOrderResult.getResult().getAllocateOrders())
            || CollectionUtils.isEmpty(transferAndForecastOrderResult.getResult().getAllocateOrderDetails())){
            throw new FacadeException("OTS-03-005-00-15-230","查询调拨预报单和调拨单");
        }
        //更新调拨预报单
        TransferAndForecastOrder transferAndForecastOrder = transferAndForecastOrderResult.getResult();
        transferAndForecastOrder.getAllocateApplyOrderDetails().forEach(allocateApplyOrderDetail -> {
            BigDecimal fulfillmentNotifyQuantity = transferAndForecastOrder.getAllocateOrderDetails().stream().filter(allocateOrderDetail ->
                            Objects.equals(InfoUtil.deleteZeroPrefix(allocateApplyOrderDetail.getOutLineNo()), InfoUtil.deleteZeroPrefix(allocateOrderDetail.getOutAllocateApplyOrderLineId())))
                    .map(AllocateOrderDetail::getBizFeatures).filter(StringUtils::isNotBlank)
                    .map(FeatureUtil::fromString)
                    .map(map -> map.get(FeaturesKey.CUMULATIVE_FULFILLMENT_NOTIFY_QUANTITY))
                    .filter(StringUtils::isNotBlank).map(String::trim).map(BigDecimal::new).reduce(BigDecimal.ZERO, BigDecimal::add);
            String bizFeatures = allocateApplyOrderDetail.getBizFeatures();
            Map<String, String> bizFeaturesMap = FeatureUtil.fromString(bizFeatures);
            bizFeaturesMap.put(FeaturesKey.CUMULATIVE_FULFILLMENT_NOTIFY_QUANTITY,fulfillmentNotifyQuantity.toString());
            com.epoch.app.crunifiedinventory.domain.allocateapplyorderdetail.dto.UpdateFeaturesRequest updateFeaturesRequest = com.epoch.app.crunifiedinventory.domain.allocateapplyorderdetail.dto.UpdateFeaturesRequest.builder().
                    mainOrderId(allocateApplyOrderDetail.getAllocateApplyOrderId().toString())
                    .lineNo(allocateApplyOrderDetail.getLineNo())
                    .bizFeatures(FeatureUtil.toString(bizFeaturesMap))
                    .build();
            allocateApplyOrderDetailService.updateFeatures(updateFeaturesRequest);
        });

    }

//    @Override
//    public TransferOrder getTransferOrder(FulfillmentOrderData fulfillmentOrderData) {
//        TransferOrderQueryRequest transferOrderQueryRequest = new TransferOrderQueryRequest();
//        transferOrderQueryRequest.setTransferOrderCode(fulfillmentOrderData.getSourceOrderNo());
//        Result<TransferOrder> transferOrderResult = transferOrderQueryService.query(transferOrderQueryRequest);
//        return Optional.ofNullable(transferOrderResult).map(Result::getResult).orElse(null);
//    }

//    @Override
//    public List<FulfillmentGetRes> getFulfillmentGetRes(FulfillmentOrderData fulfillmentOrderData) {
//        SearchFulfullmentOrderReq searchFulfullmentOrderReq = new SearchFulfullmentOrderReq();
//        searchFulfullmentOrderReq.setSourceOrderNo(fulfillmentOrderData.getSourceOrderNo());
//        searchFulfullmentOrderReq.setFulfillmentDirectionType(FulfillmentDirectionTypeEnum.FORWARD.getValue());
//        com.alibaba.cloud.retail.delivery.api.model.delivery.response.Result<List<FulfillmentGetRes>> listResult = fulfillmentOrderAbilityService.searchFulfullmentOrder(searchFulfullmentOrderReq);
//        return Optional.ofNullable(listResult).map(com.alibaba.cloud.retail.delivery.api.model.delivery.response.Result::getResult).orElse(Lists.newArrayList());
//    }

    @Override
    public FulfillmentOrderAbilityService getFulfillmentOrderAbilityService() {
        return fulfillmentOrderAbilityService;
    }

    @Override
    public TransferOrderQueryService getTransferOrderQueryService() {
        return transferOrderQueryService;
    }

    @Override
    public AllocateOrderDetailService getAllocateOrderDetailService() {
        return allocateOrderDetailService;
    }

    @Override
    public String getTransferOrderType() {
        return AllocateOrderTypeEnum.FREIGHT_YARD_PICKUP.getType().toString();
    }
}
